# -*- coding: utf-8 -*-
#############################
####### server module #######
#############################
########## INFO #############
#
# program: chat
#    file: tracker.py
#  python: version 2.6 is required
#     use: python -i tracker.py
#   autor: Alexander Anikeev
# version: 0.9.9 RC2
#  update: 26.03.11
#


# import modules
from socket import * 
from string import *
from sys import *
from threading import * 
from select import * 
from time import *
import socket, string, sys, threading, select, time, optparse
import server
from server import pack_msg, unpack_msg


#host, port
host, t_port = "192.168.1.54",  6000
#status of controlled server "MAIN"/"ALT"


class Work(Thread):
    def __init__(self):
        Thread.__init__(self)
    def run(self):
        sleep(5)
        server.start()


def start_alt(q, w, e, r):
    server.PORT=int(t_port)+2
    first_send=True
    working = False
    try:
        sock = socket.socket(AF_INET, SOCK_STREAM)
        sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        sock.connect((host, int(t_port)))
    except socket.error,  detail:
        pass
    while 1:
        i=0
        if working == True:
            try:
                sleep(2)
                sock = socket.socket(AF_INET, SOCK_STREAM)
                sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
                sock.connect((host, t_port))
                server.stop()
                working = False
                first_send = True
                server.newtopic = True
            except KeyboardInterrupt:
                exit(0)
            except: continue
        if first_send == True:
            t_msg = pack_msg("wsa", str(server.HOST)+":"+str(server.PORT), "#sys#")
            log = []
            log.extend(server.l_log)
            while len(log) > 0:
                message = pack_msg("log", log.pop(0))
                try:
                    sock.send(message)
                except socket.error:
                    if working == False:
                        work=Work()
                        work.setDaemon(True)
                        sock.close()
            if server.newtopic == True:
                message = pack_msg("tpc", server.TOPIC[-1])
                try: 
                    sock.send(message)
                except socket.error:
                    if working == False:
                        work=Work()
                        work.setDaemon(True)
                        sock.close()
            first_send = False
            code = ""
            message = ""
        else:
            t_msg = pack_msg("ask", "ping", "#sys#")
        try:
            sock.send(t_msg)
        except socket.error:
            if working == False:
                work=Work()
                work.setDaemon(True)
                work.start()
                working = True
                sock.close()
        try:
            t_msg = sock.recv(256)
        except :
            if working == False:
                work=Work()
                work.setDaemon(True)
                work.start()
                working = True
                sock.close()
            continue
        err, code, text = unpack_msg(t_msg)
        if err == 1:
            continue
        if code == "tpc":
            server.TOPIC.append(text)
            continue
        if code == "log":
            if len(server.l_log) == 20:
                del server.l_log[0]
            server.l_log.append(text)
        if code == "ask" and text == "ping":
            sleep(2)
            continue
        if not text:
            if working == False:
                work=Work()
                work.setDaemon(True)
                work.start()
                working = True
                sock.close()
                continue


def start_main(q, w, e, r):
    server.PORT=int(t_port)+1
    i=0
    try:
        s = socket.socket(AF_INET, SOCK_STREAM)
        s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        s.bind((host, int(t_port)))
    except socket.error,  detail:
        pass
    work=Work()
    work.setDaemon(True)
    print "Starting chat server"
    work.start()
    connected = False
    while 1:
        if connected == False:
            try:
                s.listen(1)
                sock, addr = s.accept()
                connected = True
            except socket.error,  detail:
                pass
            log = []
            log.extend(server.l_log)
        else:
            err, code, text = 0,  None, None  
            try: 
                t_msg = sock.recv(256)
            except socket.error, detail:
                pass
                break
            err, code, text = unpack_msg(t_msg)
            if err == 1:
                print "incorrect packet recieved, mb alt server closed"
                #notify clients about alt server close
                message = pack_msg("das", str(server.alt_servers[-1]))
                server.sendmsg(message)
                del server.alt_servers[-1]
                sock.close()
                connected = False
            if code == "tpc":
                server.TOPIC.append(text)
                continue
            if code == "wsa":
                server.alt_servers.append(text)
                sleep(2)
                message = pack_msg("aas", str(server.alt_servers[-1]))          
                server.sendmsg(message)
                code = "ask"
                text = "ping"
            if code == "log":
                if len(server.l_log) == 20:
                    del server.l_log[0]
                server.l_log.append(text)
                t_msg = pack_msg("ask", "ping", "#sys#")
                try:
                    sock.send(t_msg)
                except socket.error,  detail:
                    pass
                continue
            if server.newtopic == True:
                t_msg = pack_msg("tpc", server.TOPIC[-1])
                try:
                    sock.send(t_msg)
                except socket.error, detail:
                    pass
                server.newtopic = False
            while len(log)>0:
                t_msg = pack_msg("log", log.pop(0))
                try:
                    sock.send(t_msg)
                except socket.error,  detail:
                    pass
                t_msg =""
                code == ""
            log = server.logtext = []
            if code == "ask" and text == "ping":
                try:
                    sock.send(t_msg)
                except socket.error, detail:
                    pass
                sleep(2)

parser=optparse.OptionParser(version = "0.9.8 beta")
parser.add_option("-m", "--main", action="callback", callback=start_main, help="start main server")             
parser.add_option("-a", "--alt", action="callback", callback=start_alt, dest="host", help="start alt server", default="109.171.79.111")
(options, args)=parser.parse_args()
#EOF
